gdk: Drop generation of synthesized crossing events on grabs
authorCarlos Garnacho <carlosg@gnome.org>
Fri, 15 Sep 2017 16:31:18 +0000 (18:31 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Tue, 19 Sep 2017 16:40:50 +0000 (18:40 +0200)
GDK just needs to care about toplevels nowadays, which means these events
are already delivered from the windowing. We don't need to generate
intra-window crossing events ourselves.

gdk/gdkdisplay.c
gdk/gdkwindow.c

index bdc9dabde5db09d48b5ff7ca5fb8ecfe1158ef0c..a4a75bc2fb27dd70393e02663e561b92512d8322 100644 (file)
@@ -806,97 +806,6 @@ _gdk_display_end_touch_grab (GdkDisplay       *display,
   return FALSE;
 }
 
-/* _gdk_synthesize_crossing_events only works inside one toplevel.
-   This function splits things into two calls if needed, converting the
-   coordinates to the right toplevel */
-static void
-synthesize_crossing_events (GdkDisplay      *display,
-                            GdkDevice       *device,
-                            GdkDevice       *source_device,
-                           GdkWindow       *src_window,
-                           GdkWindow       *dest_window,
-                           GdkCrossingMode  crossing_mode,
-                           guint32          time,
-                           gulong           serial)
-{
-  GdkWindow *src_toplevel, *dest_toplevel;
-  GdkModifierType state;
-  double x, y;
-
-  if (src_window)
-    src_toplevel = gdk_window_get_toplevel (src_window);
-  else
-    src_toplevel = NULL;
-  if (dest_window)
-    dest_toplevel = gdk_window_get_toplevel (dest_window);
-  else
-    dest_toplevel = NULL;
-
-  if (src_toplevel == NULL && dest_toplevel == NULL)
-    return;
-  
-  if (src_toplevel == NULL ||
-      src_toplevel == dest_toplevel)
-    {
-      /* Same toplevels */
-      gdk_window_get_device_position_double (dest_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      src_window,
-                                      dest_window,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-    }
-  else if (dest_toplevel == NULL)
-    {
-      gdk_window_get_device_position_double (src_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                       src_window,
-                                       NULL,
-                                       device, source_device,
-                                       crossing_mode,
-                                       x, y, state,
-                                       time,
-                                       NULL,
-                                       serial, FALSE);
-    }
-  else
-    {
-      /* Different toplevels */
-      gdk_window_get_device_position_double (src_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      src_window,
-                                      NULL,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-      gdk_window_get_device_position_double (dest_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      NULL,
-                                      dest_window,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-    }
-}
-
 static GdkWindow *
 get_current_toplevel (GdkDisplay      *display,
                       GdkDevice       *device,
@@ -932,7 +841,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
                        guint32            time,
                        gulong             serial)
 {
-  GdkWindow *src_window, *pointer_window, *new_toplevel;
+  GdkWindow *pointer_window, *new_toplevel;
   GdkPointerWindowInfo *info;
   GList *old_grabs;
   GdkModifierType state;
@@ -946,26 +855,8 @@ switch_to_pointer_grab (GdkDisplay        *display,
   if (grab)
     {
       /* New grab is in effect */
-
-      /* We need to generate crossing events for the grab.
-       * However, there are never any crossing events for implicit grabs
-       * TODO: ... Actually, this could happen if the pointer window
-       *           doesn't have button mask so a parent gets the event...
-       */
       if (!grab->implicit)
        {
-         /* We send GRAB crossing events from the window under the pointer to the
-            grab window. Except if there is an old grab then we start from that */
-         if (last_grab)
-           src_window = last_grab->window;
-         else
-           src_window = info->window_under_pointer;
-
-         if (src_window != grab->window)
-            synthesize_crossing_events (display, device, source_device,
-                                        src_window, grab->window,
-                                        GDK_CROSSING_GRAB, time, serial);
-
          /* !owner_event Grabbing a window that we're not inside, current status is
             now NULL (i.e. outside grabbed window) */
          if (!grab->owner_events && info->window_under_pointer != grab->window)
@@ -1029,12 +920,6 @@ switch_to_pointer_grab (GdkDisplay        *display,
                                                 NULL, NULL);
             }
 
-         if (!info->need_touch_press_enter &&
-             pointer_window != last_grab->window)
-            synthesize_crossing_events (display, device, source_device,
-                                        last_grab->window, pointer_window,
-                                        GDK_CROSSING_UNGRAB, time, serial);
-
          /* We're now ungrabbed, update the window_under_pointer */
          _gdk_display_set_window_under_pointer (display, device, pointer_window);
        }
index f9fab82487a8dced37de61b343f4377e730d44d1..14bea5aa3d032f4c504be27e1875e0a7e8575835 100644 (file)
@@ -5466,37 +5466,6 @@ point_in_input_window (GdkWindow *window,
   return FALSE;
 }
 
-static void
-convert_toplevel_coords_to_window (GdkWindow *window,
-                                  gdouble    toplevel_x,
-                                  gdouble    toplevel_y,
-                                  gdouble   *window_x,
-                                  gdouble   *window_y)
-{
-  GdkWindow *parent;
-  gdouble x, y;
-  GList *children, *l;
-
-  x = toplevel_x;
-  y = toplevel_y;
-
-  children = NULL;
-  while ((parent = window->parent) != NULL &&
-        (parent->window_type != GDK_WINDOW_ROOT))
-    {
-      children = g_list_prepend (children, window);
-      window = parent;
-    }
-
-  for (l = children; l != NULL; l = l->next)
-    gdk_window_coords_from_parent (l->data, x, y, &x, &y);
-
-  g_list_free (children);
-
-  *window_x = x;
-  *window_y = y;
-}
-
 GdkWindow *
 _gdk_window_find_child_at (GdkWindow *window,
                           double     x,
@@ -5670,43 +5639,6 @@ gdk_window_get_support_multidevice (GdkWindow *window)
 
 /* send motion events if the right buttons are down */
 
-static GdkWindow *
-find_common_ancestor (GdkWindow *win1,
-                     GdkWindow *win2)
-{
-  GdkWindow *tmp;
-  GList *path1 = NULL, *path2 = NULL;
-  GList *list1, *list2;
-
-  tmp = win1;
-  while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
-    {
-      path1 = g_list_prepend (path1, tmp);
-      tmp = tmp->parent;
-    }
-
-  tmp = win2;
-  while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
-    {
-      path2 = g_list_prepend (path2, tmp);
-      tmp = tmp->parent;
-    }
-
-  list1 = path1;
-  list2 = path2;
-  tmp = NULL;
-  while (list1 && list2 && (list1->data == list2->data))
-    {
-      tmp = list1->data;
-      list1 = list1->next;
-      list2 = list2->next;
-    }
-  g_list_free (path1);
-  g_list_free (path2);
-
-  return tmp;
-}
-
 GdkEvent *
 _gdk_make_event (GdkWindow    *window,
                 GdkEventType  type,
@@ -5827,288 +5759,6 @@ _gdk_make_event (GdkWindow    *window,
   return event;
 }
 
-static void
-send_crossing_event (GdkDisplay                 *display,
-                    GdkWindow                  *toplevel,
-                    GdkWindow                  *window,
-                    GdkEventType                type,
-                    GdkCrossingMode             mode,
-                    GdkNotifyType               notify_type,
-                    GdkWindow                  *subwindow,
-                     GdkDevice                  *device,
-                     GdkDevice                  *source_device,
-                    gdouble                     toplevel_x,
-                    gdouble                     toplevel_y,
-                    GdkModifierType             mask,
-                    guint32                     time_,
-                    GdkEvent                   *event_in_queue,
-                    gulong                      serial)
-{
-  GdkEvent *event;
-  guint32 window_event_mask, type_event_mask;
-  GdkDeviceGrabInfo *grab;
-  GdkTouchGrabInfo *touch_grab = NULL;
-  GdkPointerWindowInfo *pointer_info;
-  gboolean block_event = FALSE;
-  GdkEventSequence *sequence;
-
-  grab = _gdk_display_has_device_grab (display, device, serial);
-  pointer_info = _gdk_display_get_pointer_info (display, device);
-
-  sequence = gdk_event_get_event_sequence (event_in_queue);
-  if (sequence)
-    touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
-
-  if (touch_grab)
-    {
-      if (window != touch_grab->window)
-        return;
-
-      window_event_mask = touch_grab->event_mask;
-    }
-  else if (grab != NULL &&
-           !grab->owner_events)
-    {
-      /* !owner_event => only report events wrt grab window, ignore rest */
-      if ((GdkWindow *)window != grab->window)
-       return;
-      window_event_mask = grab->event_mask;
-    }
-  else
-    window_event_mask = window->event_mask;
-
-  if (type == GDK_ENTER_NOTIFY &&
-      (pointer_info->need_touch_press_enter ||
-       (source_device &&
-        gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)) &&
-      mode != GDK_CROSSING_TOUCH_BEGIN &&
-      mode != GDK_CROSSING_TOUCH_END)
-    {
-      pointer_info->need_touch_press_enter = TRUE;
-      block_event = TRUE;
-    }
-  else if (type == GDK_LEAVE_NOTIFY)
-    {
-      type_event_mask = GDK_LEAVE_NOTIFY_MASK;
-      window->devices_inside = g_list_remove (window->devices_inside, device);
-
-      if (!window->support_multidevice && window->devices_inside)
-        {
-          /* Block leave events unless it's the last pointer */
-          block_event = TRUE;
-        }
-    }
-  else
-    {
-      type_event_mask = GDK_ENTER_NOTIFY_MASK;
-
-      if (!window->support_multidevice && window->devices_inside)
-        {
-          /* Only emit enter events for the first device */
-          block_event = TRUE;
-        }
-
-      if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
-          gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
-          !g_list_find (window->devices_inside, device))
-        window->devices_inside = g_list_prepend (window->devices_inside, device);
-    }
-
-  if (block_event)
-    return;
-
-  if (window_event_mask & type_event_mask)
-    {
-      event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
-      gdk_event_set_device (event, device);
-      gdk_event_set_seat (event, gdk_device_get_seat (device));
-
-      if (source_device)
-        gdk_event_set_source_device (event, source_device);
-
-      event->crossing.time = time_;
-      event->crossing.subwindow = subwindow;
-      if (subwindow)
-       g_object_ref (subwindow);
-      convert_toplevel_coords_to_window ((GdkWindow *)window,
-                                        toplevel_x, toplevel_y,
-                                        &event->crossing.x, &event->crossing.y);
-      event->crossing.x_root = toplevel_x + toplevel->x;
-      event->crossing.y_root = toplevel_y + toplevel->y;
-      event->crossing.mode = mode;
-      event->crossing.detail = notify_type;
-      event->crossing.focus = FALSE;
-      event->crossing.state = mask;
-    }
-}
-
-
-/* The coordinates are in the toplevel window that src/dest are in.
- * src and dest are always (if != NULL) in the same toplevel, as
- * we get a leave-notify and set the window_under_pointer to null
- * before crossing to another toplevel.
- */
-void
-_gdk_synthesize_crossing_events (GdkDisplay                 *display,
-                                GdkWindow                  *src,
-                                GdkWindow                  *dest,
-                                 GdkDevice                  *device,
-                                 GdkDevice                  *source_device,
-                                GdkCrossingMode             mode,
-                                double                      toplevel_x,
-                                double                      toplevel_y,
-                                GdkModifierType             mask,
-                                guint32                     time_,
-                                GdkEvent                   *event_in_queue,
-                                gulong                      serial,
-                                gboolean                    non_linear)
-{
-  GdkWindow *c;
-  GdkWindow *win, *last, *next;
-  GList *path, *list;
-  GdkWindow *a;
-  GdkWindow *b;
-  GdkWindow *toplevel;
-  GdkNotifyType notify_type;
-
-  /* TODO: Don't send events to toplevel, as we get those from the windowing system */
-
-  a = (src && GDK_IS_WINDOW (src)) ? src : NULL;
-  b = (dest && GDK_IS_WINDOW (dest)) ? dest : NULL;
-
-  if (src == dest)
-    return; /* No crossings generated between src and dest */
-
-  if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
-    {
-      if (a && gdk_window_get_device_events (src, device) == 0)
-        a = NULL;
-
-      if (b && gdk_window_get_device_events (dest, device) == 0)
-        b = NULL;
-    }
-
-  if (!a && !b)
-    return;
-
-  c = find_common_ancestor (a, b);
-
-  non_linear |= (c != a) && (c != b);
-
-  if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
-    {
-      toplevel = gdk_window_get_toplevel (a);
-
-      /* Traverse up from a to (excluding) c sending leave events */
-      if (non_linear)
-       notify_type = GDK_NOTIFY_NONLINEAR;
-      else if (c == a)
-       notify_type = GDK_NOTIFY_INFERIOR;
-      else
-       notify_type = GDK_NOTIFY_ANCESTOR;
-      send_crossing_event (display, toplevel,
-                          a, GDK_LEAVE_NOTIFY,
-                          mode,
-                          notify_type,
-                          NULL, device, source_device,
-                          toplevel_x, toplevel_y,
-                          mask, time_,
-                          event_in_queue,
-                          serial);
-
-      if (c != a)
-       {
-         if (non_linear)
-           notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-         else
-           notify_type = GDK_NOTIFY_VIRTUAL;
-
-         last = a;
-         win = a->parent;
-         while (win != c && win->window_type != GDK_WINDOW_ROOT)
-           {
-             send_crossing_event (display, toplevel,
-                                  win, GDK_LEAVE_NOTIFY,
-                                  mode,
-                                  notify_type,
-                                  (GdkWindow *)last,
-                                  device, source_device,
-                                  toplevel_x, toplevel_y,
-                                  mask, time_,
-                                  event_in_queue,
-                                  serial);
-
-             last = win;
-             win = win->parent;
-           }
-       }
-    }
-
-  if (b) /* Might not be a dest, e.g. if we're moving out of the window */
-    {
-      toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
-
-      /* Traverse down from c to b */
-      if (c != b)
-       {
-         path = NULL;
-         win = b->parent;
-         while (win != c && win->window_type != GDK_WINDOW_ROOT)
-           {
-             path = g_list_prepend (path, win);
-             win = win->parent;
-           }
-
-         if (non_linear)
-           notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-         else
-           notify_type = GDK_NOTIFY_VIRTUAL;
-
-         list = path;
-         while (list)
-           {
-             win = list->data;
-             list = list->next;
-             if (list)
-               next = list->data;
-             else
-               next = b;
-
-             send_crossing_event (display, toplevel,
-                                  win, GDK_ENTER_NOTIFY,
-                                  mode,
-                                  notify_type,
-                                  (GdkWindow *)next,
-                                  device, source_device,
-                                  toplevel_x, toplevel_y,
-                                  mask, time_,
-                                  event_in_queue,
-                                  serial);
-           }
-         g_list_free (path);
-       }
-
-
-      if (non_linear)
-       notify_type = GDK_NOTIFY_NONLINEAR;
-      else if (c == a)
-       notify_type = GDK_NOTIFY_ANCESTOR;
-      else
-       notify_type = GDK_NOTIFY_INFERIOR;
-
-      send_crossing_event (display, toplevel,
-                          b, GDK_ENTER_NOTIFY,
-                          mode,
-                          notify_type,
-                          NULL,
-                           device, source_device,
-                          toplevel_x, toplevel_y,
-                          mask, time_,
-                          event_in_queue,
-                          serial);
-    }
-}
-
 void
 _gdk_display_set_window_under_pointer (GdkDisplay *display,
                                        GdkDevice  *device,